package com.fast.fast.upms.biz.base.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fast.fast.common.base.exception.BizException;
import com.fast.fast.upms.biz.base.enums.FileType;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Date;

/**
 * 上传文件工具类
 *
 * @author lyf
 * @date 2022年11月14日
 * @date 2024年10月14日 16点50分
 */
@Slf4j
@UtilityClass
public class UploadUtil {

    /**
     * 单文件上传
     *
     * @param file     文件
     * @param dir      存放文件的目录名
     * @param fileType 文件类型枚举
     * @return 文件信息
     */
    public static JSONObject upload(MultipartFile file, String dir, FileType... fileType) {
        JSONObject jo = new JSONObject(true);
        try {
            // 文件安全校验
            safeCheck(file, fileType);

            // 文件绝对路径=工程根目录+/+存放文件的目录名
            String absolutePath = System.getProperty("user.dir") + "/" + dir;
            // 若目录不存在,则创建目录
            FileUtil.mkdir(absolutePath);

            // 文件校验码
            String checkCode = SecureUtil.md5(file.getInputStream());
            // 原始文件名
            String title = file.getOriginalFilename();
            // 文件格式
            String format = title.substring(title.lastIndexOf(".") + 1);
            // 文件名
            String name = checkCode + "." + format;
            // 文件大小,单位:KB
            String size = String.valueOf(file.getSize() / 1024);

            jo.put("title", title);
            jo.put("name", name);
            jo.put("format", format);
            jo.put("size", size);
            jo.put("checkCode", checkCode);
            jo.put("upTime", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
            //  文件相对路径
            jo.put("path1", dir + "/" + name);
            //  文件绝对路径
            jo.put("path2", absolutePath + "/" + name);

            //保存文件
            file.transferTo(new File(absolutePath + "/" + name));
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
        return jo;
    }

    /**
     * 多文件上传
     *
     * @param files    文件数组
     * @param dir      存放文件的目录名
     * @param fileType 文件类型枚举
     * @return 文件信息数组
     */
    public static JSONArray uploadBatch(MultipartFile[] files, String dir, FileType... fileType) {
        JSONArray ja = new JSONArray();
        for (MultipartFile file : files) {
            JSONObject jo = upload(file, dir, fileType);
            ja.add(jo);
        }
        return ja;
    }

    /**
     * 文件安全校验
     *
     * @param file 文件
     * @return
     */
    @SneakyThrows
    public static boolean safeCheck(MultipartFile file, FileType... type) {
        if (ObjUtil.isEmpty(file)) {
            throw new BizException("文件不能为空");
        }
        // 获取文件内容类型
        String contentType = TikaUtils.getContentType(file.getInputStream());
        // 判断文件内容类型是否安全
        if (!FileType.isSafeContent(contentType, type)) {
            throw new BizException("文件内容类型不安全，请重新上传");
        }
        String name = file.getOriginalFilename();
        // 获取文件格式
        String format = name.substring(name.lastIndexOf(".") + 1);
        // 判断文件格式是否安全
        if (!FileType.isSafeFormat(contentType, format)) {
            throw new BizException("文件格式不安全，请重新上传");
        }
        return true;
    }

}
